package 行为型模式


/**
 * 定义一个操作中的算法的骨架，而将一些步骤延迟到子类中，
 * 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
 * 为了防止子类重写父类的骨架方法，可以在父类中对骨架方法使用final。
 * 对于需要子类实现的抽象方法，一般声明为protected，使得这些方法对外部客户端不可见
 */
abstract class AbstractSetting {
    fun getSetting(key: String?): String? {
        var value = lookupCache(key)
        if (value == null) {
            value = readFromDatabase(key)
            putIntoCache(key, value)
        }
        return value
    }

    // 钩子方法
    fun readFromDatabase(key: String?): String {
        return "Hello World!"
    }

    protected abstract fun lookupCache(key: String?): String?
    protected abstract fun putIntoCache(key: String?, value: String?)
}

class LocalSetting : AbstractSetting() {
    private val cache: MutableMap<String?, String?> = HashMap()
    override fun lookupCache(key: String?): String? {
        return cache[key]
    }

    override fun putIntoCache(key: String?, value: String?) {
        cache[key] = value
    }
}